#include "ipc/sem.h"
#include "ipc/mutex.h"
#include "cpu/irq.h"
#include "tools/list.h"


void sem_init(sem_t* sem,int init_count)
{
    sem->count = init_count;
    list_init(&sem->wait_list);
}


void sem_wait(sem_t* sem)
{
    irq_state  irq_state = int_enter_protection();
    if(sem->count>0)
    {
        sem->count--;
    }
    else
    {
        task_t* cur = cur_task();
        //从就绪队列移除
        task_set_block(cur);
        //加入信号量等待队列
        list_insert_last(&sem->wait_list,&cur->wait_node);
        //切换进程
        task_dispatch();
    }
    int_leave_protection(irq_state);
    
}
void sem_notify(sem_t* sem)
{
    irq_state  irq_state = int_enter_protection();
    if(list_count(&sem->wait_list))
    {
        list_node* node=list_remove_first(&sem->wait_list);
        task_t* task=list_node_parent(node,task_t,wait_node);
        task_set_ready(task);

        task_dispatch();
    }
    else
    {
        sem->count++;
    }
    int_leave_protection(irq_state);

}


int sem_count (sem_t * sem) 
{
    irq_state  irq_state = int_enter_protection();
    int count = sem->count;
    int_leave_protection(irq_state);
    return count;
}